package _16_hash_table;

import org.junit.Test;

import java.util.*;


/**
 * @author: mornd
 * @dateTime: 2023/6/20 - 22:45
 */
public class MyTest2 {
    @Test
    public void test() {
        /*
            给定一个数组，和一个target值，找出数组中两个元素和等于target的元素下标
         */
        int[] arr = {1, 4, 6, 8, 10};
        int target = 16;

        HashTable hashTable = new HashTable();
        for (int i = 0; i < arr.length; i++) {
            int search = target - arr[i];
            if (hashTable.get(search) != null) {
                System.out.println("这俩个数下标分别是：" + hashTable.get(search) + ", " + i);
                break;
            } else {
                hashTable.put(arr[i], i);
            }
        }
    }

    /*
      给定一个字符串，求出字符串中最大不重复子串的长度
         */
    @Test
    public void test2() {
        /*
            a b a c d e c e
         */
        String str = "abacdecefghijkf";
//        String str = "abba";
        HashTable hashTable = new HashTable();
        int start = 0, end = 0, maxLen = 0;
        for (; end < str.length(); end++) {
            char c = str.charAt(end);
            if (hashTable.get(c) != null) {
                start = Math.max((int) hashTable.get(c) + 1, start);
            }
            hashTable.put(c, end);

            maxLen = Math.max(end - start + 1, maxLen);
            System.out.println(str.substring(start, end + 1));
        }
//        System.out.println(start + "-" + (end - 1));
        System.out.println("maxLen=" + maxLen);
    }

    // 字母异位词分组
    @Test
    public void test3() {
        String[] arr = {"acb", "cba", "fgt", "tgf"};
        Map<String, List<String>> map = new HashMap<>();
        for (String s : arr) {
            char[] chars = s.toCharArray();
            Arrays.sort(chars);
            String s1 = new String(chars);
            List<String> list = map.computeIfAbsent(s1, k -> new ArrayList<>());
            list.add(s1);
        }
        System.out.println(map);
    }

    // 判断单词是否有重复元素
    @Test
    public void test4() {
        String str = "abcc";
        HashMap<Character, Object> map = new HashMap<>();
        Object obj = new Object();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (map.put(c, obj) != null) {
                System.out.println("存在");
                return;
            }
        }
        System.out.println("不存在");
    }

    // 找出出现一次的单词
    @Test
    public void test5() {
        int[] arr = {1, 3, 2, 5, 2, 3, 5};

        HashSet<Integer> set = new HashSet<>();
        for (int i : arr) {
            if (!set.add(i)) {
                set.remove(i);
            }
        }
        System.out.println(set);
    }

    /*
        使用异或（前提，数组至少有1个元素，并且不相同的元素就1个，相同的元素只能相同2个）
        任何相同的数字异或，结果都是0
        任何数与0异或，结果都是其本身
     */
    @Test
    public void test5_2() {
        int[] arr = {1, 3, 5, 2, 2, 3, 5};
        int num = arr[0];
        for (int i = 1; i < arr.length; i++) {
            num = num ^ arr[i];
            System.out.println(num);
        }
    }

    // 判断两个单词是否为字母异位词
    @Test
    public void test6() {
        String s1 = "abc";
        String s2 = "bcaa";
        char[] c1 = s1.toCharArray();
        Arrays.sort(c1);
        String sortS = new String(c1);

        char[] c2 = s2.toCharArray();
        Arrays.sort(c2);
        String sortS2 = new String(c2);
        System.out.println(sortS.equals(sortS2));
    }

    @Test
    public void test6_2() {
        String s1 = "abca";
        String s2 = "bcaa";
        System.out.println(Arrays.equals(getKey(s1), getKey(s2)));

    }

    private int[] getKey(String str) {
        char[] chars = str.toCharArray();
        int[] arr = new int[26];
        for (char ch : chars) {
            arr[ch - 97]++;
        }
        return arr;
    }

    @Test
    public void test7() {
        String str = "bob + hit, ball.";
        String[] split = str.split("[^A-Za-z]+");
        System.out.println(Arrays.toString(split)); // [bob, hit, ball]
    }

    // map的compute用法
    @Test
    public <K,V> void test8() {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "a");
        int key = 1;
        /*
            key 存在，return null   删除该k
            key 存在，return 不为null   return的值替换该value
            key 不存在，return null   什么也不做
            key 不存在，return 不为null   map新增该key和value
         */
        // key=要查找的key，k=key，v=查找到的value，如果key不存在，v=null
        map.compute(key, (k, v) -> {
            System.out.println(k + ":" + v);
            return "aa";
        });

        System.out.println(map);
    }

}
